package com.dream.rpc.proxy;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.dream.RpcApp;
import com.dream.rpc.model.RpcRequest;
import com.dream.rpc.model.RpcResponse;
import com.dream.rpc.serializer.JdkSerializer;
import com.dream.rpc.serializer.Serializer;
import com.dream.rpc.serializer.SerializerFactory;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ServiceLoader;

/**
 * 服务代理（jdk动态代理）
 * @author Dreamer
 */
public class   ServiceProxy implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        ServiceLoader<Serializer> load = ServiceLoader.load(Serializer.class);
        for (Serializer serializer : load) {
            System.out.println(serializer);
        }

        //发送请求的序列化


        //            // http 请求
//            // 指定序列化器
            Serializer serializer = SerializerFactory.getInstance(RpcApp.getRpcConfig().getSerializer());
//            byte[] bodyBytes = serializer.serialize(rpcRequest);
//            RpcResponse rpcResponse = doHttpRequest(selectedServiceMetaInfo, bodyBytes, serializer);


        //构造请求
        RpcRequest rpcRequest = RpcRequest.builder()
                .serviceName(method.getDeclaringClass().getName())
                .methodName(method.getName())
                .parameterTypes(method.getParameterTypes())
                .args(args)
                .build();
        try {
            //序列化请求
            byte[] serialized = serializer.serialize(rpcRequest);
            //请求服务
            try(HttpResponse execute = HttpRequest.post("localhost:8080")
                    .body(serialized)
                    .execute();){
                byte[] result = execute.bodyBytes();
                //反序列化响应值
                RpcResponse deserialize = serializer.deserialize(result, RpcResponse.class);

                return deserialize.getData();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
